package cn.picclife.mwx.manager.sys.service.impl;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import cn.picclife.mwx.manager.sys.mapper.ScreenShotMapper;
import cn.picclife.mwx.manager.sys.model.bo.DataResponse;
import cn.picclife.mwx.manager.sys.model.bo.ScreenShotBo;
import cn.picclife.mwx.manager.sys.model.po.ScreenShot;
import cn.picclife.mwx.manager.sys.model.po.ScreenShotMap;
import cn.picclife.mwx.manager.sys.service.IFileUploader;
import cn.picclife.mwx.manager.util.Base64Utils;
import cn.picclife.mwx.manager.util.DateUtil;
import cn.picclife.mwx.manager.util.enums.ResponseStatusEnum;
import sun.misc.BASE64Encoder;

@Service
public class FileUploaderImp implements IFileUploader {
	private static final Log log = LogFactory.getLog(FileUploaderImp.class);
	private String allowSuffix = "png,gif,jpg,jpeg,bmp,tiff,txt,xml,pdf,zip,rar,doc,ppt,xls,docx,pptx,xlsx,html,htm,webp";// 允许文件格式
	private long allowSize = 5L * 1024 * 1024;// 允许文件大小
	//private String rootDir = "/app/data/img/";
	//private String fileDir ="/app/data/video/";
	
	@Value("${file.rootdir}")
	private String rootDir;
	@Value("${file.filedir}")
	private String fileDir;
	
//	private String rootDir = "D:/img/";
	
	@Autowired
	private ScreenShotMapper mapper;
	
	@Override
	public DataResponse saveFile(ScreenShotBo shot) throws Exception {
		String seqNo = DateUtil.date2String(DateUtil.sysTimestamp(), "yyyyMMddHHmmssSSS");
		String fileName = seqNo + "_OTHER.jpg";
		DataResponse msg = saveFile(shot.getBaseCode(), fileName, "",shot.getCollectId());//============
		if("200".equals(msg.getCode())){
			ScreenShot screenShot = new ScreenShot();
			screenShot.setId(UUID.randomUUID().toString().replace("-", ""));
			screenShot.setCutDir(msg.getMsg());
			screenShot.setCollectId(shot.getCollectId());
			screenShot.setWhereCutName(shot.getWhereCutName());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			screenShot.setCutTime(sdf.parse(shot.getCutTime()));
			mapper.saveData(screenShot);
		}
		return msg;
	}
	
	@Override
	public DataResponse saveFile(MultipartFile file) {
		String fileName = file.getOriginalFilename();
		long fileSize = file.getSize();
		log.info("=== fileSize：" + fileSize + "=== fileName：" + fileName);
		DataResponse msg = this.check(fileName, fileSize, null);
		if ("201".equals(msg.getCode()))
			return msg;
		try {
			msg = this.saveFile("", fileName, fileSize, file.getInputStream());
			return msg;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public DataResponse saveFile(String file, String fileName, String fileNo) {
		DataResponse msg = this.check(fileName, file.length(), null);
		if ("201".equals(msg.getCode()))
			return msg;
		byte[] byteFile = Base64.getMimeDecoder().decode(file.substring(file.indexOf(",") + 1));
//		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
//		// 判断尾缀是否为PDF
//		if(suffix.equals("pdf")){
//			msg = savePdfFile(fileNo, fileName, byteFile.length, file.substring(file.indexOf(",") + 1));
//		}else{
		InputStream sbs = new ByteArrayInputStream(byteFile);
		msg = this.saveFile(fileNo, fileName, byteFile.length, sbs);
//		}
		return msg;
	}

	private DataResponse check(String fileName, long fileSize, String localFileSize) {
		DataResponse msg = new DataResponse();
		if (fileName == null || fileName.equals("")) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg(ResponseStatusEnum.FAIL_CODE.getName());
		}
		if (localFileSize != null && fileSize != Long.parseLong(localFileSize)) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg("上传文件为[" + Long.parseLong(localFileSize) / 1024 + "]KB，实际接收[" + fileSize / 1024 + "]KB，请重新上传");
		}
		if (fileName.indexOf(".") < 0) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg("只能上传扩展名为[" + allowSuffix + "]的文件");
		}
		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		if (allowSuffix.indexOf(suffix) == -1) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg("只能上传扩展名为[" + allowSuffix + "]的文件");
		}
		if (fileSize <= 0) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg("文件必须大于0KB");
		}
		if (fileSize > allowSize) {
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg("文件最大不能超过[5M]");
		}
		return msg;
	}

	private DataResponse saveFile(String file_no, String fileName, long fileSize, InputStream in,String id) {
		if (file_no == null || "".equals(file_no))
			file_no = UUID.randomUUID().toString().replace("-", "");

		//String relativePath = rootDir + DateUtil.date2String(new Date(), "yyyy/MM/dd") + "/";// 相对路径
		String relativePath = fileDir + DateUtil.date2String(new Date(), "yyyy/MM/dd") + "/"+id+"/";// 相对路径
		String absolutePath = relativePath;// 绝对路径

		File destFile = new File(absolutePath);
		if (!destFile.exists())
			destFile.mkdirs();

		// 文件夹赋权
		String osName = System.getProperty("os.name");
		if (osName.contains("Linux")) {
			Process process = null;
			try {
				process = Runtime.getRuntime().exec("chmod -R 755 " + relativePath.split("/")[0]);
			} catch (IOException e) {
				log.error(e);
			}
		}

		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		String newFileName = "file_" + file_no + "_" + DateUtil.date2String(DateUtil.sysTimestamp(), "yyyyMMddHHmmssSSS") + "." + suffix;
		File f = new File(absolutePath + newFileName);
		int byteread = 0; // 读取的字节数
		OutputStream out = null;
		try {
			if (!f.exists())
				f.createNewFile();
			out = new FileOutputStream(f);
			byte[] buffer = new byte[1024];
			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			try {
				if (in != null)
					in.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		DataResponse msg = new DataResponse();
		if (f.length() != fileSize) {
			msg.setMsg("上传文件为[" + fileSize / 1024 + "]KB，实际接收[" + f.length() / 1024 + "]KB，请重新上传");
			return msg;
		}
		msg.setCode(ResponseStatusEnum.SUCCESS_CODE.getCode());
		msg.setMsg(absolutePath + "" + newFileName);
		return msg;
	}

	
	private DataResponse saveFile(String file_no, String fileName, long fileSize, InputStream in) {
		if (file_no == null || "".equals(file_no))
			file_no = UUID.randomUUID().toString().replace("-", "");

		String relativePath = rootDir + DateUtil.date2String(new Date(), "yyyy/MM/dd") + "/";// 相对路径

		String absolutePath = relativePath;// 绝对路径

		File destFile = new File(absolutePath);
		if (!destFile.exists())
			destFile.mkdirs();

		// 文件夹赋权
		String osName = System.getProperty("os.name");
		if (osName.contains("Linux")) {
			Process process = null;
			try {
				process = Runtime.getRuntime().exec("chmod -R 755 " + relativePath.split("/")[0]);
			} catch (IOException e) {
				log.error(e);
			}
		}

		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		String newFileName = "file_" + file_no + "_" + DateUtil.date2String(DateUtil.sysTimestamp(), "yyyyMMddHHmmssSSS") + "." + suffix;
		File f = new File(absolutePath + newFileName);
		int byteread = 0; // 读取的字节数
		OutputStream out = null;
		try {
			if (!f.exists())
				f.createNewFile();
			out = new FileOutputStream(f);
			byte[] buffer = new byte[1024];
			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			try {
				if (in != null)
					in.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		DataResponse msg = new DataResponse();
		if (f.length() != fileSize) {
			msg.setMsg("上传文件为[" + fileSize / 1024 + "]KB，实际接收[" + f.length() / 1024 + "]KB，请重新上传");
			return msg;
		}
		msg.setCode(ResponseStatusEnum.SUCCESS_CODE.getCode());
		msg.setMsg(absolutePath + "" + newFileName);
		return msg;
	}

	public DataResponse savePdfFile(String file_no, String fileName, long fileSize, String base64sString) {
		DataResponse msg = new DataResponse();
		if (file_no == null || "".equals(file_no))
			file_no = UUID.randomUUID().toString().replace("-", "");

		String relativePath = rootDir + DateUtil.date2String(new Date(), "yyyy/MM/dd") + "/";// 相对路径
		String absolutePath = relativePath;// 绝对路径

		File destFile = new File(absolutePath);
		if (!destFile.exists())
			destFile.mkdirs();
		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		String newFileName = "file_" + file_no + "_" + DateUtil.date2String(DateUtil.sysTimestamp(), "yyyyMMddHHmmssSSS") + "." + suffix;
		Base64Utils.base64StringToPDF(base64sString, absolutePath + newFileName);
		// 文件夹赋权
		String osName = System.getProperty("os.name");
		if (osName.contains("Linux")) {
			Process process = null;
			try {
				process = Runtime.getRuntime().exec("chmod -R 755 " + relativePath.split("/")[0]);
			} catch (IOException e) {
				log.error(e);
			}
		}
		return msg;
	}

	@Override
	public DataResponse queryFileByCollectId(ScreenShotBo shot) throws Exception {
		DataResponse msg = new DataResponse();
		ScreenShot screenShot = new ScreenShot();
		if(shot.getCollectId() == null || "".equals(shot.getCollectId().trim())){
			msg.setCode(ResponseStatusEnum.FAIL_CODE.getCode());
			msg.setMsg(ResponseStatusEnum.FAIL_CODE.getName() + "：collectId不能为空");
			return msg;
		}
		screenShot.setCollectId(shot.getCollectId());
		List<ScreenShotMap> listSst = mapper.queryDataById(screenShot);
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (ScreenShotMap sst : listSst) {
			Map<String, Object> map = new HashMap<String, Object>();

//			String base64 = ImageToBase64(sst.getCutDir());
//			map.put("cut_dir", sst.getCutDir());
			
			String url ="";
			if("1".equals(sst.getArchiveFlag())) {
				url = sst.getArchiveUrl();
			}else {
				url = sst.getCutDir();
			}			
			String base64 = ImageToBase64(url);
			map.put("cut_dir", url);

			
			map.put("cut_time", sst.getCutTime());

			map.put("where_cut_name", sst.getWhereCutName());
			map.put("base_code", "data:image/jpg;base64," + base64.replaceAll("\r\n", ""));
			list.add(map);
		}
		msg.setMsg(ResponseStatusEnum.SUCCESS_CODE.getName());
		msg.setCode(ResponseStatusEnum.SUCCESS_CODE.getCode());
		msg.setData(list);
		return msg;
	}

	/**
	 * 图片转换Base64     
	 * @param imgPath    
	 */
	public static String ImageToBase64(String imgPath) {
		InputStream in = null;
		byte[] data = null;
		// 读取图片字节数组
		try {
			in = new FileInputStream(imgPath);
			data = new byte[in.available()];
			in.read(data);
		} catch (IOException e) {
			log.error(e);
		}finally {
			try{
				if(in!=null){
					in.close();
				}
			}catch(Exception e){
				log.error(e);
			}
		}
		// 对字节数组Base64编码
		BASE64Encoder encoder = new BASE64Encoder();
		// 返回Base64编码过的字节数组字符串
		return encoder.encode(data);
	}

	@Override
	public DataResponse saveFile(String file, String fileName, String fileNo, String id) {

		DataResponse msg = this.check(fileName, file.length(), null);
		if ("201".equals(msg.getCode()))
			return msg;
		byte[] byteFile = Base64.getMimeDecoder().decode(file.substring(file.indexOf(",") + 1));
//		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
//		// 判断尾缀是否为PDF
//		if(suffix.equals("pdf")){
//			msg = savePdfFile(fileNo, fileName, byteFile.length, file.substring(file.indexOf(",") + 1));
//		}else{
		InputStream sbs = new ByteArrayInputStream(byteFile);
		msg = this.saveFile(fileNo, fileName, byteFile.length, sbs,id);
//		}
		return msg;
	
	}
}
